package core;

import java.util.HashMap;
import java.util.Map.Entry;

import Classificadores.Classificadores;

public class Voting {

	Corpus corpus;
	Hierarquia hierarquia;
	int democratic_type;
	
	public Voting(Corpus _corpus, Hierarquia _hierarquia, int _tipoVotacao){
		corpus=_corpus;
		hierarquia=_hierarquia;
		democratic_type=_tipoVotacao;
	}
	
	public Classificadores exec(){
		Classificadores democracia = new Classificadores();
		democracia.myName=new String("DEMOCRACIA_TIPO_"+democratic_type);
		
		ConfusionMatrix conf = new ConfusionMatrix(hierarquia);
		
		for(int i=0; i<corpus.listaDocumentos.length; i++){
			for(int j=0; j<corpus.listaDocumentos[i].sentenceList.length; j++){
				
				HashMap<String, Pair<Integer, Double>> contadorEtiquetas = new HashMap<String, Pair<Integer, Double>>();
				for (Entry<String, Pair<String, Double>> it_etiquetasFrase : corpus.listaDocumentos[i].sentenceList[j].etiquetasClassificadores.entrySet()) {
					insereHash(contadorEtiquetas, it_etiquetasFrase.getValue().getKey(), it_etiquetasFrase.getValue().getValue());
				}
				
				
				String etiqueta=new String();
				int max_ocurrencias=0;
				double max_confianca=0;
				HashMap<String, Integer> labelsCorpus = new HashMap<String, Integer>();
				if(democratic_type==2){
					contaLabelsCorpus(labelsCorpus);
				}
				for (Entry<String,Pair<Integer,Double>> it : contadorEtiquetas.entrySet()) {
					if(it.getValue().getKey()>max_ocurrencias){
						max_ocurrencias=it.getValue().getKey();
						etiqueta=it.getKey();
						max_confianca=it.getValue().getValue();
					}else{
						//CASO DE EMPATE DE VOTOS
						switch (democratic_type) {
						case 1: //desempate peloa confianca dos classificadores
							if(it.getValue().getKey()==max_ocurrencias && max_confianca<it.getValue().getValue()){
								etiqueta=it.getKey();
								max_confianca=it.getValue().getValue();
							}							
							break;
						case 2: //desempate pelo numero de etiquetas no treino
							if(it.getValue().getKey()==max_ocurrencias && labelsCorpus.get(etiqueta)<labelsCorpus.get(it.getKey())){
								etiqueta=it.getKey();
							}
							break;
						default:
							break;
						}
						
					}
				}
				conf.insereMatrix(etiqueta, corpus.listaDocumentos[i].sentenceList[j].categoriaTemp);
			}
		}
		democracia.conf=conf;
		return democracia;
	}
	
	
	public void insereHash(HashMap<String, Pair<Integer, Double>> hash, String etiqueta, Double confianca){
		if(hash.containsKey(etiqueta)){
			hash.put(etiqueta, new Pair<Integer, Double>(hash.get(etiqueta).getKey()+1, hash.get(etiqueta).getValue()+confianca));
		}else{
			hash.put(etiqueta, new Pair<Integer, Double>(1, confianca));
		}
	}
	
	public void contaLabelsCorpus(HashMap<String, Integer> hash){
		for(int i=0; i<corpus.listaDocumentos.length; i++){
			for(int j=0; j<corpus.listaDocumentos[i].sentenceList.length; j++){
				if(hash.containsKey(corpus.listaDocumentos[i].sentenceList[j].categoriaTemp)){
					hash.put(corpus.listaDocumentos[i].sentenceList[j].categoriaTemp, hash.get(corpus.listaDocumentos[i].sentenceList[j].categoriaTemp)+1);
				}else{
					hash.put(corpus.listaDocumentos[i].sentenceList[j].categoriaTemp, 1);
				}
			}
		}	
	}
	
}
